#include "main.h"

struct user_link*L_user=NULL;//账号链
struct client_link*L_client=NULL;//客户端链
int S;//服务器描述符
int epoll_listen0,epoll_listen1;//TCP监听列表
pthread_mutex_t pm1,pm2;//互斥锁
int main(int argc, const char *argv[])
{
	//建立账户信息链表和在线客户端链表
	L_user=create_user_link();
	L_client=create_client_link();
	if(L_user==NULL || L_client==NULL)return -1;	
	//建立本机IP、port信息结构体
	struct sockaddr_in addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(6666);
	addr.sin_addr.s_addr=inet_addr("0.0.0.0");


	//**************************************************TCP********************************************
	int S;
	if((S=socket(AF_INET,SOCK_STREAM,0))==-1){perror("创建TCP套接字失败");return -1;}
	if(bind(S,(struct sockaddr*)&addr,sizeof(addr))==-1){perror("绑定本机TCP失败");return -1;}
	listen(S,10);

	//***********************epoll***********************
	//创建epoll列表
	epoll_listen0=epoll_create(EPOLL_CLOEXEC);
	epoll_listen1=epoll_create(EPOLL_CLOEXEC);
	struct epoll_event test={0};test.events=EPOLLIN;
	test.data.fd=S;//加入服务器描述符
	epoll_ctl(epoll_listen0,EPOLL_CTL_ADD,S,&test);
	test.data.fd=0;//加入标准输入描述符
	epoll_ctl(epoll_listen0,EPOLL_CTL_ADD,0,&test);
	//创建监听返回数组
	struct epoll_event epoll_buf[2]={0};
	//***************************************************

	//*********************客户端数据**********************
	int CC,ret,to_data;//客户端描述符//read返回值//返回客户端
	struct sockaddr_in client_addr={0};
	int client_addr_len=sizeof(client_addr);
	struct login_data client_login_date={0};
	//***************************************************
	

	//*********************创建线程***********************
	//初始化互斥锁
	pthread_mutex_init(&pm1,NULL);
	pthread_mutex_init(&pm2,NULL);
	pthread_t server_tcp;
	if(ret=pthread_create(&server_tcp,NULL,server_TCP_fun,NULL)!=0){printf("创建TCP线程失败:%d\n",ret);return -1;}
	//**************************************************
	
	while(1)//接收客户端数据
	{

		printf("\n阻塞等待客户端连接请求...");fflush(stdout);
		int len=epoll_wait(epoll_listen0,epoll_buf,2,-1);
		for(int i=0;i<len;i++)
		{
			if(epoll_buf[i].data.fd==S)
			{
				CC=accept(S,(struct sockaddr*)&client_addr,&client_addr_len);
				if(CC==-1){perror("与客户端建立连接失败");break;}
				printf("\n####客户端<%s>建立连接\n",inet_ntoa(client_addr.sin_addr));
				ret=read(CC,&client_login_date,sizeof(struct login_data));
				if(ret==-1){perror("读取客户端信息失败");continue;}
				if(ret==0){printf("客户端断开连接\n");continue;}
				//***************************************反馈客户端**********************************************
				////查询
				int find_user_ret=find_user(L_user,client_login_date.userID);
				int find_client_ret=find_client(L_client,client_login_date.userID);
				if(client_login_date.type==1)//登陆
				{
					//0:登陆成功
					//-1:账号不存在
					//-2:密码错误
					//-3:已登陆
					//-4:登陆失败
					if(find_user_ret==0)//账号密码正确
					{
						if(find_client_ret==0)//已登陆
							to_data=-3;
						else if(find_client_ret==-1)//未登陆
						{
							test.data.fd=CC;
							if(epoll_ctl(epoll_listen1,EPOLL_CTL_ADD,CC,&test)==0)//加入监听列表
							{
								if(client_link_ctl(L_client,1,client_addr,client_login_date.userID.name)==0)//加入客户端链
								{
									printf("####客户端<%s><%s>加入监听列表\n",inet_ntoa(client_addr.sin_addr),client_login_date.userID.name);
									to_data=0;
								}
								else
								{
									printf("将客户端添加至客户端链失败\n");
									to_data=-4;
								}
							}
							else
							{
								perror("将客户端添加至监听列表失败");
								to_data=-4;
							}
						}
					}
					else if(find_user_ret==-1)//密码错误
						to_data=-2;
					else if(find_user_ret==-2)//账号不存在
						to_data=-1;
				}
				//****************************************注册*****************************************
				else if(client_login_date.type==2)
				{
					//0:注册成功
					//-1:账号已存在
					//-2;注册失败
					if(find_user_ret==-2)//不存在
					{
						if(user_link_ctl(L_user,1,client_login_date.userID)==0)
						{
							printf("##注册账户<%s>成功\n",client_login_date.userID.name);
							to_data=0;
						}
						else
						{
							//printf("##注册账户<%s>失败\n",client_login_date.userID.name);
							to_data=-2;
						}
					}
					else
					{
						//printf("##注册账户<%s>已存在\n",client_login_date.userID.name);
						to_data=-1;
					}
				}
				////反馈客户端
				printf("反馈客户端<ret=%d\n",to_data);
				write(CC,&to_data,4);
				if(client_login_date.type!=1||to_data!=0)
				{
					close(CC);
					printf("####客户端<%s>断开连接\n",inet_ntoa(client_addr.sin_addr));
				}
			}
			else if(epoll_buf[i].data.fd==0)
			{
				char buf[128]={0};
				scanf("%127s",buf);
				while(getchar()!=10);
				printf("获取标准输入流输入:%s",buf);
			}
		}
	}
	return 0;
}
